/**************************************************************
*
* M3D_TR.H
*
* Transformations without scale based on quaternions support
**************************************************************/

#ifndef _M3D_TR_H_
#define _M3D_TR_H_

#pragma once

class m3dTR {
public:
   m3dV    tran;    // translation transform as a 3D vector
   m3dQUAT rot;    // rotation transform as a quaternion

   m3dTR (void) : tran(m3dVZero), rot()                                                      {}
   m3dTR (const m3dV& transVec, const m3dQUAT& rotateQuat) : tran(transVec), rot(rotateQuat) {}

   void Identity       (void);
   void Invert         (void);
   void Invert         (m3dTR *res) const;
   void SetTransform   (const m3dV* transVec, const m3dQUAT* rotateQuat);
   void SetTranslation (const m3dV* transVec);
   void SetRotation    (const m3dQUAT* rotateQuat);
   void SetDif        (const m3dTR *trFrom, const m3dTR *trTo);

   void SetMatr        (const m3dMATR *matr);
   void GetMatr        (m3dMATR *matr) const;

   void Transform      (const m3dV *a, m3dV *res) const;
   void Transform      (m3dV *vct) const;
   void Transform      (const m3dTR *a, m3dTR *res) const;
   void Transform      (m3dTR *tr) const;
   void Transform      (m3dMATR *matr, int OperOrder) const;
   void ApplyTo        (m3dMATR *matr) const;

   BOOL CheckValid     (void) const;
};

/**************************************************************
* m3dMultiplyTr()
*
**************************************************************/
__INLINE void m3dMultiplyTr (const m3dTR *a, const m3dTR *b, m3dTR *res)
{
   m3dV extraTrans;
   a->rot.Transform(&b->tran, &extraTrans);
   res->tran.x = a->tran.x + extraTrans.x;
   res->tran.y = a->tran.y + extraTrans.y;
   res->tran.z = a->tran.z + extraTrans.z;
   m3dMultiplyQuat(&a->rot, &b->rot, &res->rot);
}

#define       m3dIsEqualTr(a, b) m3dIsEqualTr_A(a, b, M3D_EPSILON)
#define       m3dIsZeroTr(a)     m3dIsZeroQuat_A(a, M3D_EPSILON)
extern BOOL   m3dIsEqualTr_A (const m3dTR *a, const m3dTR *b, float acc);
extern BOOL   m3dIsZeroTr_A  (const m3dTR *a, float acc);

extern m3dTR m3dTrIdentity;

#endif // _M3D_TR_H_
//
// End of file 'M3D_TR.H'
//
